<?php


namespace app\common\utils;

class Rsa
{
	const PKCS1 = 0;
	const PKCS8 = 7;
	private $rsa_public;
	private $rsa_private;
	private $pkcs;
	private $padding;
	public function __construct($rsa_public, $rsa_private, $pkcs = self::PKCS8, $padding = OPENSSL_PKCS1_PADDING)
	{
		$this->rsa_public = $rsa_public;
		$this->rsa_private = $rsa_private;
		$this->pkcs = $pkcs;
		$this->padding = $padding;
	}
	public function sign($str)
	{
		openssl_sign($str, $sign, $this->getPrivateKey());
		return base64_encode($sign);
	}
	public function encrypt($content) : string
	{
		$crypto = "";
		$pu_key = $this->getPublicKey();
		foreach (str_split($content, $this->pkcs == self::PKCS1 ? 117 : 245) as $chunk) {
			openssl_public_encrypt($chunk, $encryptData, $pu_key, $this->padding);
			$crypto .= $encryptData;
		}
		return $crypto;
		return base64_encode($crypto);
	}
	public function decrypt($content) : ?string
	{
		if (!is_string($content)) {
			return null;
		}
		$decrypted = "";
		$chunks = str_split($content, $this->pkcs == self::PKCS1 ? 128 : 256);
		foreach ($chunks as $chunk) {
			$partial = "";
			$decryptIsTrue = openssl_private_decrypt($chunk, $partial, $this->getPrivateKey(), $this->padding);
			if ($decryptIsTrue === false) {
				return null;
			}
			$decrypted .= $partial;
		}
		return $decrypted;
	}
	public function getPublicKey()
	{
		if ($this->pkcs == self::PKCS1) {
			$search = ["-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----", "\n", "\r", "\r\n"];
			$public_key = str_replace($search, "", $this->rsa_public);
			$public_key = $search[0] . PHP_EOL . wordwrap($public_key, 64, "\n", true) . PHP_EOL . $search[1];
		} else {
			$public_key = $this->rsa_public;
		}
		$key = openssl_pkey_get_public($public_key);
		if (!$key) {
			$this->throwError("公钥不可用");
		}
		return $key;
	}
	public function getPrivateKey()
	{
		if ($this->pkcs == self::PKCS1) {
			$search = ["-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----", "\n", "\r", "\r\n"];
			$private_key = str_replace($search, "", $this->rsa_private);
			$private_key = $search[0] . PHP_EOL . wordwrap($private_key, 64, "\n", true) . PHP_EOL . $search[1];
		} else {
			$private_key = $this->rsa_private;
		}
		$pi_key = openssl_pkey_get_private($private_key);
		if (!$pi_key) {
			$this->throwError("私钥不可用");
		}
		return $pi_key;
	}
	public function throwError($msg)
	{
		throw new \Exception($msg);
	}
	public static function getNewKey($pkcs) : array
	{
		$config = ["digest_alg" => "sha512", "private_key_bits" => $pkcs == self::PKCS1 ? 1024 : 2048, "private_key_type" => OPENSSL_KEYTYPE_RSA];
		$res = openssl_pkey_new($config);
		openssl_pkey_export($res, $private_key);
		$public_key = openssl_pkey_get_details($res)["key"];
		return ["public_key" => $public_key, "private_key" => $private_key];
	}
	public function test()
	{
		$config = ["digest_alg" => "sha512", "private_key_bits" => 1024, "private_key_type" => OPENSSL_KEYTYPE_RSA];
		$res = openssl_pkey_new($config);
		openssl_pkey_export($res, $private_key);
		$public_key = openssl_pkey_get_details($res)["key"];
		$rsa = ["public_key" => $public_key, "private_key" => $private_key];
		return json($rsa);
		$private_key = "-----BEGIN RSA PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALcgalk3Y80yW5N5
hj6hWZ1o4++cAkm22lBNF264i0qcfm3ZB22nXbJcR3VIHWW7HFDpj/Xs9330pw2x
x69eZurg6dtbu2/uaXVzzyHIGKjXugyBr4rhGsf3MXgX0U6lr96DQQnu8lxRDGlQ
RcyKmfXPiwFpLoFiaSHBpdQRwS7JAgMBAAECgYADi8AjbBwlnAUD7QV5bvxiPOa0
/AtbTAwcI/IBNdeUoUUdcWdgay44RusnTTcsghwBQRSFiYodSUB21mtsbOKHP1VZ
C8Z0qJxMrm7bmKukUVWNBXKrlkuVXUZEH5saJvr232xMZppZgcOqEUzve0h87laL
BEojNrVR68iJQgy1pQJBAPJts3thbY/qvaVVRc7axJ0m6FRhN6wpM2+aDkQJ5HhL
cvei+Ihr13XG37RCDWw3HJQM7aBKVHGU7VYw6t3SrFcCQQDBYNheVXvMpmaP1G6H
AzB9LGMePPgHuI7o5tDwYS9BI33TMsf9RVY7qnAytYSSY5y/VKZ6lmgUbZjcvR+N
ggnfAkEAx+z+Sm7zqu88zP+A3XF/Gdb/XK77+afUumHDCAtcdnRKcLze16qP+poy
3HZomWjt0Y7D3R/PeggGnsEiwCLAawJAHdcU7FGinezbjLxKJflfBSHRVbwwxfg7
zUK44S8N/K4+X1XJuJJ3gROG5rxN7c0DRh8I5YfKHcTfvshMUyjK3wJBANuLdRGU
u9mlhjt9VmRkyN96gEYfYrMw0mSkttG02qF9ONnDmHmbCZuHHwglysklOWVDX0fx
8j7DkUSxxtdfcwA=
-----END RSA PRIVATE KEY-----";
		$public_key = "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3IGpZN2PNMluTeYY+oVmdaOPv
nAJJttpQTRduuItKnH5t2Qdtp12yXEd1SB1luxxQ6Y/17Pd99KcNscevXmbq4Onb
W7tv7ml1c88hyBio17oMga+K4RrH9zF4F9FOpa/eg0EJ7vJcUQxpUEXMipn1z4sB
aS6BYmkhwaXUEcEuyQIDAQAB
-----END PUBLIC KEY-----";
		$bizContent = ["supplierCode" => "202372000142021000064", "type" => "1", "surrenderTime" => "2021-09-10 15:30:00"];
		for ($i = 0; $i < 50; $i++) {
			$bizContent[$i] = "2021-09-10 15:30:00测试" . $i;
		}
		$bizContent = json_encode($bizContent);
		$utilRsa = new RSA($public_key, "");
		$bizContent_k = base64_encode($utilRsa->encrypt($bizContent));
		$res_bizContent = "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";
		$res = (new RSA("", $private_key))->decrypt(base64_decode($res_bizContent));
		return $res;
	}
}